﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraEditors.Repository;
using System.ComponentModel.Design;
using DevExpress.XtraGrid;
using DevExpress.XtraEditors.Registrator;
using DevExpress.XtraEditors.ViewInfo;
using DevExpress.XtraScheduler.UI;

namespace ProgNetComponentsDx.Design
{
    [ToolboxItem(false)]
    internal partial class RepositoryData : XtraUserControl
    {
        private const string EditNone = "<NULL>";

        private RepositoryData()
        {
            InitializeComponent();
        }
        private GridColumn GridCol;
        private DataColumn DataCol;
        private bool isInitializing = true;
        public RepositoryData(GridColumn column)
        {
            InitializeComponent();
            teName.Text = column.Name;
            teField.Text = column.FieldName;

            this.GridCol = column;
            GetDataCol();
            PrepareCombo();
            GetAvilableRepositories();
            Repository = column.ColumnEdit;
            cbEditType.EditValue = EditNone;
            if (Repository != null)
            {
                cbRepositories.EditValue = Repository.Name;
                cbEditType.Properties.ReadOnly = true;
                SetRepItemType();
            }
            else
            {
                cbRepositories.EditValue = EditNone;
            }
            isInitializing = false;
        }
        private void SetRepItemType()
        {
            if (Repository != null)
                cbEditType.EditValue = Repository.EditorTypeName;
        }
        private void GetDataCol()
        {
            if (GridCol != null && GridCol.FieldName.IsNotNull())
            {
                if (GridCol.View != null)
                {
                    DataTable dt = null;
                    if (GridCol.View.DataSource is DataTable)
                        dt = (GridCol.View.DataSource as DataTable);
                    else if (GridCol.View.DataSource is DataView)
                        dt = (GridCol.View.DataSource as DataView).Table;
                    if (dt != null)
                    {
                        if (dt.Columns.Contains(GridCol.FieldName))
                            DataCol = dt.Columns[GridCol.FieldName];
                    }
                    else
                    {
                        if (GridCol.View.DataSource == null)
                        {
                            foreach(GridLevelNode node in GridCol.View.GridControl.LevelTree.Nodes){
                                if (node.LevelTemplate == GridCol.View)
                                {
                                    DataSet ds = null;
                                    if(GridCol.View.GridControl != null)
                                        ds = GridCol.View.GridControl.DataSource as DataSet;
                                    if(ds!=null){
                                        if (ds.Relations.Contains(node.RelationName))
                                        {
                                            DataRelation rel = ds.Relations[node.RelationName];
                                            if (rel.ChildTable.Columns.Contains(GridCol.FieldName))
                                            {
                                                DataCol = rel.ChildTable.Columns[GridCol.FieldName];
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        private RepositoryItem repository;
        public RepositoryItem Repository
        {
            get { return repository; }
            private set
            {
                repository = value;
                PreparePropertyGrid();
            }
        }
        private void PreparePropertyGrid()
        {
            propertyGridControl1.SelectedObject = repository;
            propertyGridControl1.RetrieveFields();
        }
        private bool CanProcess()
        {
            return GridCol != null;
        }

        private Dictionary<string, EditorClassInfo> editors = new Dictionary<string, EditorClassInfo>();

        private void PrepareCombo()
        {
            cbEditType.Properties.Items.Clear();
            cbEditType.Properties.Items.Add(EditNone);

            foreach (EditorClassInfo info in EditorRegistrationInfo.Default.Editors)
            {
                AddInfo(info);
            }
            
            AddInfo(new EditorClassInfo("MonthEdit", typeof(MonthEdit), typeof(RepositoryItemMonth),
                typeof(ButtonEditViewInfo), new DevExpress.XtraEditors.Drawing.ButtonEditPainter(), true));
        }

        private void AddInfo(EditorClassInfo info)
        {
            string name = info.Name;
            if (!editors.ContainsKey(name))
            {
                cbEditType.Properties.Items.Add(name);
                editors.Add(name, info);
            }
        }
        private Dictionary<string, RepositoryItem> repositories = new Dictionary<string, RepositoryItem>();

        public void GetAvilableRepositories()
        {
            if (cbRepositories != null && cbRepositories.Properties != null && cbRepositories.Properties.Items != null)
            {
                cbRepositories.Properties.Items.Clear();
            }
            repositories.Clear();
            cbRepositories.Properties.Items.Add(EditNone);
            if (CanProcess())
            {
                if (GridCol.View != null)
                {
                    foreach (RepositoryItem item in GridCol.View.GridControl.RepositoryItems)
                    {
                        cbRepositories.Properties.Items.Add(item.Name);
                        repositories.Add(item.Name, item);
                    }
                }
            }
        }
        IDesignerHost host = null;
        public IDesignerHost Host
        {
            get { return host; }
            set { host = value; }
        }
        private void PrepareRepository()
        {
            if (CanProcess())
            {
                if (host != null)
                {
                    string repName = "rep_";
                    if( GridCol.FieldName.IsNotNull())
                        repName += GridCol.FieldName;
                    else
                        repName += GridCol.Name;
                    string n = repName;
                    int i =1;
                    if (host != null)
                    {
                        while (host.Container.Components[repName] != null)
                        {
                            repName = n + i;
                            i++;
                        }
                    }
                    RepositoryItem item = null;
                    switch (cbEditType.SelectedItem.AsString())
                    {
                        case EditNone:
                            item = null;
                            break;
                        default:
                            item = host.CreateComponent(EditorRegistrationInfo.Default.Editors[cbEditType.SelectedItem.AsString()].RepositoryType, repName) as RepositoryItem;

                           // item = EditorRegistrationInfo.Default.CreateRepositoryItem(cbEditType.SelectedItem.AsString());
                            if (item is RepositoryItemLookUpEdit)
                            {
                                (item as RepositoryItemLookUpEdit).Buttons.Clear();
                                (item as RepositoryItemLookUpEdit).Buttons.Add(new DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo));
                            }
                            else if (item is RepositoryItemButtonEdit)
                            {
                                (item as RepositoryItemButtonEdit).Buttons.Clear();
                                (item as RepositoryItemButtonEdit).CreateDefaultButton();
                            }
                            item.Name = repName;
                            if (item.Site != null)
                                item.Site.Name = repName;

                            if (DataCol != null && (item is RepositoryItemTextEdit))
                            {
                                (item as RepositoryItemTextEdit).MaxLength = DataCol.MaxLength > 0 ? DataCol.MaxLength : 0;
                                (item as RepositoryItemTextEdit).NullText = "";
                            }
                            break;
                    }
                    Repository = item;
                    
                    if (Repository != null)
                    {
                        if (!GridCol.View.GridControl.RepositoryItems.Contains(Repository))
                        {
                            GridCol.View.GridControl.RepositoryItems.Add(Repository);
                        }
                    }
                }
            }
        }

        private void cbRepositories_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!isInitializing)
            {
                if (cbRepositories.EditValue.AsString() != EditNone)
                {
                    cbEditType.EditValue = EditNone;
                    cbEditType.Properties.ReadOnly = true;
                    Repository = repositories[cbRepositories.EditValue.AsString()];
                }
                else
                {
                    cbEditType.Properties.ReadOnly = false;
                    Repository = null;
                }
                isInitializing = true;
                SetRepItemType();
                isInitializing = false;
            }
        }

        private void cbEditType_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!isInitializing)
            {
                // PrepareRepository();
            }
        }
        public void AssignRepository()
        {
            GridCol.ColumnEdit = Repository;
           
            GetAvilableRepositories();
            if (Repository != null)
            {
                cbRepositories.EditValue = Repository.Name;
            }
        }
        private void btnAssign_Click(object sender, EventArgs e)
        {
            AssignRepository();
        }

        private void cbRepositories_QueryPopUp(object sender, CancelEventArgs e)
        {
            GetAvilableRepositories();
        }

        private void propertyGridControl1_CellValueChanged(object sender, DevExpress.XtraVerticalGrid.Events.CellValueChangedEventArgs e)
        {
            GetAvilableRepositories();
            if (Repository != null)
            {
                cbRepositories.EditValue = Repository.Name;
            }
        }

        internal void CreateDefault()
        {
            if (DataCol != null)
            {
                if (DataCol.DataType == typeof(int) ||
                    DataCol.DataType == typeof(decimal) ||
                    (DataCol.DataType == typeof(double) ||
                    (DataCol.DataType == typeof(float))))
                {
                    cbEditType.EditValue = "SpinEdit";
                }
                else if (DataCol.DataType == typeof(string))
                {
                    if (DataCol.MaxLength > 50)
                        cbEditType.EditValue = "MemoExEdit";
                    else
                        cbEditType.EditValue = "TextEdit";
                }
                else if (DataCol.DataType == typeof(DateTime))
                {
                    cbEditType.EditValue = "DateEdit";
                }
                else if (DataCol.DataType == typeof(Array))
                {
                    cbEditType.EditValue = "PictureEdit";
                }
                else if (DataCol.DataType == typeof(bool))
                {
                    cbEditType.EditValue = "CheckEdit";
                }
                else
                {
                    cbEditType.EditValue = "TextEdit";
                }
            }
            PrepareRepository();
        }

        private void btnCreate_Click(object sender, EventArgs e)
        {
            if (!isInitializing)
            {
                PrepareRepository();
            }
        }
    }
}


